home *** CD-ROM | disk | FTP | other *** search
/ Info-Mac 4 / Info_Mac IV CD-ROM (Pacific HiTech Inc.)(August 1994).iso / Development / Source / Telnet 2.6.1d1 4⁄26⁄94 Folder / Krb / encrypt.c < prev    next >
Text File  |  1994-02-20  |  26KB  |  1,022 lines

  1. /*-
  2.  * Copyright (c) 1991 The Regents of the University of California.
  3.  * All rights reserved.
  4.  *
  5.  * Redistribution and use in source and binary forms are permitted provided
  6.  * that: (1) source distributions retain this entire copyright notice and
  7.  * comment, and (2) distributions including binaries display the following
  8.  * acknowledgement:     ``This product includes software developed by the
  9.  * University of California, Berkeley and its contributors'' in the
  10.  * documentation or other materials provided with the distribution and in
  11.  * all advertising materials mentioning features or use of this software.
  12.  * Neither the name of the University nor the names of its contributors may
  13.  * be used to endorse or promote products derived from this software without
  14.  * specific prior written permission.
  15.  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
  16.  * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
  17.  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  18.  */
  19.  
  20. #ifndef lint
  21. static char sccsid[] = "@(#)encrypt.c    5.1 (Berkeley) 2/28/91";
  22. #endif /* not lint */
  23.  
  24. /*
  25.  * Copyright (C) 1990 by the Massachusetts Institute of Technology
  26.  *
  27.  * Export of this software from the United States of America is assumed
  28.  * to require a specific license from the United States Government.
  29.  * It is the responsibility of any person or organization contemplating
  30.  * export to obtain such a license before exporting.
  31.  *
  32.  * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
  33.  * distribute this software and its documentation for any purpose and
  34.  * without fee is hereby granted, provided that the above copyright
  35.  * notice appear in all copies and that both that copyright notice and
  36.  * this permission notice appear in supporting documentation, and that
  37.  * the name of M.I.T. not be used in advertising or publicity pertaining
  38.  * to distribution of the software without specific, written prior
  39.  * permission.    M.I.T. makes no representations about the suitability of
  40.  * this software for any purpose.  It is provided "as is" without express
  41.  * or implied warranty.
  42.  */
  43.  
  44. #ifdef MPW
  45. #pragma segment 22
  46. #endif
  47.  
  48. #define NCSA_ENC
  49.  
  50. #ifdef TN3270
  51. #pragma segment 3270tcp
  52. #if !defined(USEDUMP)
  53.     #include "maclib.h"
  54.     #include "termdef.h"
  55.     #include "tn3270funcs.h"
  56.     #include "globals.h"
  57. #else
  58.     #pragma load "tn3270DumpFile"
  59. #endif
  60. #include "telnet.h"
  61. #endif /* tn3270 */
  62.  
  63. #ifdef NCSA_ENC
  64. #include "TelnetHeader.h"
  65. #include "wind.h"
  66. #include "parse.proto.h"
  67. #endif
  68.  
  69. #include <stdarg.h>
  70.  
  71. #define TELCMDS 1
  72. #define TELOPTS 1
  73.  
  74. #define ENCRYPT_NAMES
  75.  
  76. #include "encrypt.h"
  77.  
  78. #include "enc_des.proto.h"
  79. #include "encrypt.proto.h"
  80. #include "kerberos.proto.h"
  81. /* #include "wdefpatch.proto.h" */
  82.  
  83. #ifdef    __STDC__
  84. #include <stdlib.h>
  85. #endif
  86. #ifdef    NO_STRING_H
  87. #include <strings.h>
  88. #else
  89. #include <string.h>
  90. #endif
  91.  
  92. #define typemask(x)        ((x) > 0 ? 1 << ((x)-1) : 0)
  93. #define kOurHit    32
  94.  
  95. static Encryptions encryptions[] = {
  96.     { "DES_CFB64",        ENCTYPE_DES_CFB64,
  97.                         (void(*)()) cfb64_encrypt,    
  98.                         (long(*)()) cfb64_decrypt,
  99.                         (void(*)()) cfb64_init,
  100.                         (long(*)()) cfb64_start,
  101.                         (long(*)()) cfb64_is,
  102.                         (long(*)()) cfb64_reply,
  103.                         (void(*)()) cfb64_session,
  104.                         (long(*)()) cfb64_keyid,
  105.                         (void(*)()) cfb64_printsub },
  106.     { "DES_OFB64",        ENCTYPE_DES_OFB64,
  107.                         (void(*)()) ofb64_encrypt,    
  108.                         (long(*)()) ofb64_decrypt,
  109.                         (void(*)()) ofb64_init,
  110.                         (long(*)()) ofb64_start,
  111.                         (long(*)()) ofb64_is,
  112.                         (long(*)()) ofb64_reply,
  113.                         (void(*)()) ofb64_session,
  114.                         (long(*)()) ofb64_keyid,
  115.                         (void(*)()) ofb64_printsub },
  116.     { 0, },
  117. };
  118.  
  119. #define I_SUPPORT_ENCRYPT        (tw->i_support_encrypt & ~tw->i_wont_support_encrypt)
  120. #define I_SUPPORT_DECRYPT        (tw->i_support_decrypt & ~tw->i_wont_support_decrypt)
  121.  
  122. static unsigned char str_send_init[] = { IAC, SB, OPT_ENCRYPT,
  123.                                          ENCRYPT_SUPPORT };
  124. static unsigned char str_start_init[] = { IAC, SB, OPT_ENCRYPT };
  125. static unsigned char str_end_init[] = { IAC, SB, OPT_ENCRYPT, 0, IAC, SE };
  126.  
  127. static struct key_info ki_init[2] = {
  128.     { { 0 }, 0, DIR_ENCRYPT, 0, findencryption },
  129.     { { 0 }, 0, DIR_DECRYPT, 0, finddecryption },
  130. };
  131.  
  132. #ifdef    ENCRYPT_NAMES
  133. char *encrypt_names[] = {
  134.     "IS", "SUPPORT", "REPLY", "START", "END",
  135.     "REQUEST-START", "REQUEST-END", "ENC-KEYID", "DEC-KEYID",
  136.     0,
  137. };
  138. char *enctype_names[] = {
  139.     "ANY", "DES_CFB64",  "DES_OFB64",  0,
  140. };
  141. #else
  142. extern char *encrypt_names[];
  143. extern char *enctype_names[];
  144. #endif
  145.  
  146.  
  147. #define    ENCRYPT_NAME_OK(x)    ((x) >= 0 && (x) < ENCRYPT_CNT)
  148. #define    ENCRYPT_NAME(x)        encrypt_names[x]
  149.  
  150. #define    ENCTYPE_NAME_OK(x)    ((x) >= 0 && (x) < ENCTYPE_CNT)
  151. #define    ENCTYPE_NAME(x)        enctype_names[x]
  152.  
  153. Encryptions *findencryption (CDATA *tw, long type)
  154. {
  155.     Encryptions *ep = encryptions;
  156.  
  157.     if (!(I_SUPPORT_ENCRYPT & tw->remote_supports_decrypt & typemask(type)))
  158.         return(0);
  159.     while (ep->type && ep->type != type)
  160.         ++ep;
  161.     return(ep->type ? ep : 0);
  162. }
  163.  
  164. Encryptions *finddecryption (CDATA *tw, long type)
  165. {
  166.     Encryptions *ep = encryptions;
  167.  
  168.     if (!(I_SUPPORT_DECRYPT & tw->remote_supports_encrypt & typemask(type)))
  169.         return(0);
  170.     while (ep->type && ep->type != type)
  171.         ++ep;
  172.     return(ep->type ? ep : 0);
  173. }
  174.  
  175. void encrypt_init (CDATA *tw, char *name, long server)
  176. {
  177.     Encryptions *ep = encryptions;
  178.  
  179. //    tw->will_wont_resp_encrypt = 0;
  180. //    tw->do_dont_resp_encrypt = 0;
  181. //    tw->o_encrypt = 0;
  182.     tw->encrypt_debug_mode = 0; /* TelInfo->debug; ddd */
  183.     tw->Name = name;
  184.     tw->Server = server;
  185.     tw->i_support_encrypt = tw->i_support_decrypt = 0;
  186.     tw->remote_supports_encrypt = tw->remote_supports_decrypt = 0;
  187.     tw->encrypt_mode = 0;
  188.     tw->decrypt_mode = 0;
  189.     tw->encrypt_output = 0;
  190.     tw->decrypt_input = 0;
  191.     tw->encrypt_verbose = 0; /* TelInfo->debug; ddd */
  192.     tw->autoencrypt = 1;                /* ... was 0 */
  193.     tw->autodecrypt = 1;                /* ... was 0 */
  194.     tw->havesessionkey = 0;
  195.     tw->i_wont_support_encrypt = 0;
  196.     tw->i_wont_support_decrypt = 0;
  197.     xbcopy(str_send_init, tw->str_send, sizeof(str_send_init));
  198.     xbcopy(str_start_init, tw->str_start, sizeof(str_start_init));
  199.     xbcopy(str_end_init, tw->str_end, sizeof(str_end_init));
  200.     xbcopy(ki_init, tw->ki, sizeof(ki_init));
  201.     tw->ki[0].modep = &tw->encrypt_mode;
  202.     tw->ki[1].modep = &tw->decrypt_mode;
  203.     
  204.     tw->str_suplen = 4;
  205.  
  206.     while (ep->type) {
  207.         if (tw->encrypt_debug_mode)
  208.             xprintf(tw, ">>>%s: I will support %s\r\n",
  209.                    tw->Name, ENCTYPE_NAME(ep->type));
  210.         tw->i_support_encrypt |= typemask(ep->type);
  211.         tw->i_support_decrypt |= typemask(ep->type);
  212.         if ((tw->i_wont_support_decrypt & typemask(ep->type)) == 0)
  213.             if ((tw->str_send[tw->str_suplen++] = ep->type) == IAC)
  214.                 tw->str_send[tw->str_suplen++] = IAC;
  215.         if (ep->init)
  216.             (*ep->init)(tw, tw->Server);
  217.         ++ep;
  218.     }
  219.     tw->str_send[tw->str_suplen++] = IAC;
  220.     tw->str_send[tw->str_suplen++] = SE;
  221. }
  222.  
  223. #ifdef notdef
  224. void encrypt_list_types ()
  225. {
  226.     Encryptions *ep = encryptions;
  227.  
  228.     xprintf(tw, "Valid encryption types:\n");
  229.     while (ep->type) {
  230.            xprintf(tw, "\t%s (%d)\r\n", ENCTYPE_NAME(ep->type), ep->type);
  231.         ++ep;
  232.     }
  233. }
  234.  
  235.  
  236. long EncryptEnable (CDATA *tw, char *type, char *mode)
  237. {
  238.     if (isprefix(type, "help") || isprefix(type, "?")) {
  239.         xprintf(tw, "Usage: encrypt enable <type> [input|output]\n");
  240.         encrypt_list_types();
  241.         return(0);
  242.     }
  243.     if (EncryptType(tw, type, mode))
  244.         return(EncryptStart(tw, mode));
  245.     return(0);
  246. }
  247.  
  248. long EncryptDisable (CDATA *tw, char *type, char *mode)
  249. {
  250.     register Encryptions *ep;
  251.     long ret = 0;
  252.  
  253.     if (isprefix(type, "help") || isprefix(type, "?")) {
  254.         xprintf(tw, "Usage: encrypt disable <type> [input|output]\n");
  255.         encrypt_list_types();
  256.     } else if ((ep = (Encryptions *)genget(type, encryptions,
  257.                                            sizeof(Encryptions))) == 0) {
  258.         xprintf(tw, "%s: invalid encryption type\n", type);
  259.     } else if (Ambiguous(ep)) {
  260.         xprintf(tw, "Ambiguous type '%s'\n", type);
  261.     } else {
  262.         if ((mode == 0) || (isprefix(mode, "input") ? 1 : 0)) {
  263.             if (tw->decrypt_mode == ep->type)
  264.                 EncryptStopInput(tw);
  265.             tw->i_wont_support_decrypt |= typemask(ep->type);
  266.             ret = 1;
  267.         }
  268.         if ((mode == 0) || (isprefix(mode, "output"))) {
  269.             if (tw->encrypt_mode == ep->type)
  270.                 EncryptStopOutput(tw);
  271.             tw->i_wont_support_encrypt |= typemask(ep->type);
  272.             ret = 1;
  273.         }
  274.         if (ret == 0)
  275.             xprintf(tw, "%s: invalid encryption mode\n", mode);
  276.     }
  277.     return(ret);
  278. }
  279.  
  280. long EncryptType (CDATA *tw, char *type, char *mode)
  281. {
  282.     register Encryptions *ep;
  283.     long ret = 0;
  284.  
  285.     if (isprefix(type, "help") || isprefix(type, "?")) {
  286.         xprintf(tw, "Usage: encrypt type <type> [input|output]\n");
  287.         encrypt_list_types();
  288.     } else if ((ep = (Encryptions *)genget(type, encryptions,
  289.                                            sizeof(Encryptions))) == 0) {
  290.         xprintf(tw, "%s: invalid encryption type\n", type);
  291.     } else if (Ambiguous(ep)) {
  292.         xprintf(tw, "Ambiguous type '%s'\n", type);
  293.     } else {
  294.         if ((mode == 0) || isprefix(mode, "input")) {
  295.             tw->decrypt_mode = ep->type;
  296.             tw->i_wont_support_decrypt &= ~typemask(ep->type);
  297.             ret = 1;
  298.         }
  299.         if ((mode == 0) || isprefix(mode, "output")) {
  300.             tw->encrypt_mode = ep->type;
  301.             tw->i_wont_support_encrypt &= ~typemask(ep->type);
  302.             ret = 1;
  303.         }
  304.         if (ret == 0)
  305.             xprintf(tw, "%s: invalid encryption mode\n", mode);
  306.     }
  307.     return(ret);
  308. }
  309.  
  310. long EncryptStart (CDATA *tw, char *mode)
  311. {
  312.     register long ret = 0;
  313.  
  314.     if (mode) {
  315.         if (isprefix(mode, "input"))
  316.             return(EncryptStartInput(tw));
  317.         if (isprefix(mode, "output"))
  318.             return(EncryptStartOutput(tw));
  319.         if (isprefix(mode, "help") || isprefix(mode, "?")) {
  320.             xprintf(tw, "Usage: encrypt start [input|output]\n");
  321.             return(0);
  322.         }
  323.         xprintf(tw, "%s: invalid encryption mode 'encrypt start ?' for help\n", mode);
  324.         return(0);
  325.     }
  326.     ret += EncryptStartInput(tw);
  327.     ret += EncryptStartOutput(tw);
  328.     return(ret);
  329. }
  330.  
  331. long EncryptStartInput (CDATA *tw)
  332. {
  333.     if (tw->decrypt_mode) {
  334.         encrypt_send_request_start(tw);
  335.         return(1);
  336.     }
  337.     xprintf(tw, "No previous decryption mode, decryption not enabled\r\n");
  338.     return(0);
  339. }
  340.  
  341. long EncryptStartOutput (CDATA *tw)
  342. {
  343.     if (tw->encrypt_mode) {
  344.         encrypt_start_output(tw, tw->encrypt_mode);
  345.         return(1);
  346.     }
  347.     xprintf(tw, "No previous encryption mode, encryption not enabled\r\n");
  348.     return(0);
  349. }
  350.  
  351. long EncryptStop (CDATA *tw, char *mode)
  352. {
  353.     long ret = 0;
  354.     if (mode) {
  355.         if (isprefix(mode, "input"))
  356.             return(EncryptStopInput(tw));
  357.         if (isprefix(mode, "output"))
  358.             return(EncryptStopOutput(tw));
  359.         if (isprefix(mode, "help") || isprefix(mode, "?")) {
  360.             xprintf(tw, "Usage: encrypt stop [input|output]\n");
  361.             return(0);
  362.         }
  363.         xprintf(tw, "%s: invalid encryption mode 'encrypt stop ?' for help\n", mode);
  364.         return(0);
  365.     }
  366.     ret += EncryptStopInput(tw);
  367.     ret += EncryptStopOutput(tw);
  368.     return(ret);
  369. }
  370.  
  371. long EncryptStopInput (CDATA *tw)
  372. {
  373.     encrypt_send_request_end(tw);
  374.     return(1);
  375. }
  376.  
  377. long EncryptStopOutput (CDATA *tw)
  378. {
  379.     encrypt_send_end(tw);
  380.     return(1);
  381. }
  382.  
  383. void encrypt_display (CDATA *tw)
  384. {
  385.     if (tw->encrypt_output)
  386.         xprintf(tw, "Currently encrypting output with %s\r\n",
  387.                ENCTYPE_NAME(tw->encrypt_mode));
  388.     if (tw->decrypt_input)
  389.         xprintf(tw, "Currently decrypting input with %s\r\n",
  390.                ENCTYPE_NAME(tw->decrypt_mode));
  391. }
  392.  
  393. long EncryptStatus (CDATA *tw)
  394. {
  395.     if (tw->encrypt_output)
  396.         xprintf(tw, "Currently encrypting output with %s\r\n",
  397.                ENCTYPE_NAME(tw->encrypt_mode));
  398.     else if (tw->encrypt_mode) {
  399.         xprintf(tw, "Currently output is clear text.\r\n");
  400.         xprintf(tw, "Last encryption mode was %s\r\n",
  401.                ENCTYPE_NAME(tw->encrypt_mode));
  402.     }
  403.     if (tw->decrypt_input) {
  404.         xprintf(tw, "Currently decrypting input with %s\r\n",
  405.                ENCTYPE_NAME(tw->decrypt_mode));
  406.     } else if (tw->decrypt_mode) {
  407.         xprintf(tw, "Currently input is clear text.\r\n");
  408.         xprintf(tw, "Last decryption mode was %s\r\n",
  409.                ENCTYPE_NAME(tw->decrypt_mode));
  410.     }
  411.     return 1;
  412. }
  413. #endif
  414.  
  415. void encrypt_send_support (CDATA *tw)
  416. {
  417.     if (tw->str_suplen) {
  418.         /*
  419.          * If the user has requested that decryption start
  420.          * immediatly, then send a "REQUEST START" before
  421.          * we negotiate the type.
  422.          */
  423.         if (!tw->Server && tw->autodecrypt)
  424.             encrypt_send_request_start(tw);
  425.         net_write(tw->wp, (char *)tw->str_send, tw->str_suplen);
  426. /* ddd    printsub(">", &tw->str_send[2], tw->str_suplen - 2, tw); */
  427.         tw->str_suplen = 0;
  428.     }
  429. }
  430.  
  431. long EncryptDebug (CDATA *tw, long on)
  432. {
  433.     if (on < 0)
  434.         tw->encrypt_debug_mode ^= 1;
  435.     else
  436.         tw->encrypt_debug_mode = on;
  437.     xprintf(tw, "Encryption debugging %s\r\n",
  438.            tw->encrypt_debug_mode ? "enabled" : "disabled");
  439.     return(1);
  440. }
  441.  
  442. long EncryptVerbose (CDATA *tw, long on)
  443. {
  444.     if (on < 0)
  445.         tw->encrypt_verbose ^= 1;
  446.     else
  447.         tw->encrypt_verbose = on;
  448.     xprintf(tw, "Encryption %s verbose\r\n",
  449.            tw->encrypt_verbose ? "is" : "is not");
  450.     return(1);
  451. }
  452.  
  453. long EncryptAutoEnc (CDATA *tw, long on)
  454. {
  455.     encrypt_auto(tw, on);
  456.     xprintf(tw, "Automatic encryption of output is %s\r\n",
  457.            tw->autoencrypt ? "enabled" : "disabled");
  458.     return(1);
  459. }
  460.  
  461. long EncryptAutoDec (CDATA *tw, long on)
  462. {
  463.     decrypt_auto(tw, on);
  464.     xprintf(tw, "Automatic decryption of input is %s\r\n",
  465.            tw->autodecrypt ? "enabled" : "disabled");
  466.     return(1);
  467. }
  468.  
  469.  
  470. /*
  471.  * Called when ENCRYPT SUPPORT is received.
  472.  */
  473. void encrypt_support (CDATA *tw, unsigned char *typelist, long cnt)
  474. {
  475.     register long type, use_type = 0;
  476.     Encryptions *ep;
  477.  
  478.     /*
  479.      * Forget anything the other side has previously told us.
  480.      */
  481.     tw->remote_supports_decrypt = 0;
  482.  
  483.     while (cnt-- > 0) {
  484.         type = *typelist++;
  485.         if (tw->encrypt_debug_mode)
  486.             xprintf(tw, ">>>%s: He is supporting %s (%d)\r\n",
  487.                    tw->Name,
  488.                    ENCTYPE_NAME(type), type);
  489.         if ((type < ENCTYPE_CNT) &&
  490.             (I_SUPPORT_ENCRYPT & typemask(type))) {
  491.             tw->remote_supports_decrypt |= typemask(type);
  492.             if (use_type == 0)
  493.                 use_type = type;
  494.         }
  495.     }
  496.     if (use_type) {
  497.         ep = findencryption(tw, use_type);
  498.         if (!ep)
  499.             return;
  500.         type = ep->start ? (*ep->start)(tw, DIR_ENCRYPT, tw->Server) : 0;
  501.         if (tw->encrypt_debug_mode)
  502.             xprintf(tw, ">>>%s: (*ep->start)() returned %d\r\n",
  503.                    tw->Name, type);
  504.         if (type < 0)
  505.             return;
  506.         tw->encrypt_mode = use_type;
  507.         if (type == 0)
  508.             encrypt_start_output(tw, use_type);
  509.     }
  510. }
  511.  
  512. void encrypt_is (CDATA *tw, unsigned char *data, long cnt)
  513. {
  514.     Encryptions *ep;
  515.     register long type, ret;
  516.  
  517.     if (--cnt < 0)
  518.         return;
  519.     type = *data++;
  520.     if (type < ENCTYPE_CNT)
  521.         tw->remote_supports_encrypt |= typemask(type);
  522.     if (!(ep = finddecryption(tw, type))) {
  523.         if (tw->encrypt_debug_mode)
  524.             xprintf(tw, ">>>%s: Can't find type %s (%d) for initial negotiation\r\n",
  525.                    tw->Name,
  526.                    ENCTYPE_NAME_OK(type)
  527.                    ? ENCTYPE_NAME(type) : "(unknown)",
  528.                    type);
  529.         return;
  530.     }
  531.     if (!ep->is) {
  532.         if (tw->encrypt_debug_mode)
  533.             xprintf(tw, ">>>%s: No initial negotiation needed for type %s (%d)\r\n",
  534.                    tw->Name,
  535.                    ENCTYPE_NAME_OK(type)
  536.                    ? ENCTYPE_NAME(type) : "(unknown)",
  537.                    type);
  538.         ret = 0;
  539.     } else {
  540.         ret = (*ep->is)(tw, data, cnt);
  541.         if (tw->encrypt_debug_mode)
  542.             xprintf(tw, "(*ep->is)(%x, %d) returned %s(%d)\n", data, cnt,
  543.                    (ret < 0) ? "FAIL " :
  544.                    (ret == 0) ? "SUCCESS " : "MORE_TO_DO ", ret);
  545.     }
  546.     if (ret < 0) {
  547.         tw->autodecrypt = 0;
  548.     } else {
  549.         tw->decrypt_mode = type;
  550.         if (ret == 0 && tw->autodecrypt)
  551.             encrypt_send_request_start(tw);
  552.     }
  553. }
  554.  
  555. void encrypt_reply (CDATA *tw, unsigned char *data, long cnt)
  556. {
  557.     Encryptions *ep;
  558.     register long ret, type;
  559.  
  560.     if (--cnt < 0)
  561.         return;
  562.     type = *data++;
  563.     if (!(ep = findencryption(tw, type))) {
  564.         if (tw->encrypt_debug_mode)
  565.             xprintf(tw, ">>>%s: Can't find type %s (%d) for initial negotiation\r\n",
  566.                    tw->Name,
  567.                    ENCTYPE_NAME_OK(type)
  568.                    ? ENCTYPE_NAME(type) : "(unknown)",
  569.                    type);
  570.         return;
  571.     }
  572.     if (!ep->reply) {
  573.         if (tw->encrypt_debug_mode)
  574.             xprintf(tw, ">>>%s: No initial negotiation needed for type %s (%d)\r\n",
  575.                    tw->Name,
  576.                    ENCTYPE_NAME_OK(type)
  577.                    ? ENCTYPE_NAME(type) : "(unknown)",
  578.                    type);
  579.         ret = 0;
  580.     } else {
  581.         ret = (*ep->reply)(tw, data, cnt);
  582.         if (tw->encrypt_debug_mode)
  583.             xprintf(tw, "(*ep->reply)(%x, %d) returned %s(%d)\n",
  584.                    data, cnt,
  585.                    (ret < 0) ? "FAIL " :
  586.                    (ret == 0) ? "SUCCESS " : "MORE_TO_DO ", ret);
  587.     }
  588.     if (tw->encrypt_debug_mode)
  589.         xprintf(tw, ">>>%s: encrypt_reply returned %d\n", tw->Name, ret);
  590.     if (ret < 0) {
  591.         tw->autoencrypt = 0;
  592.     } else {
  593.         tw->encrypt_mode = type;
  594.         if (ret == 0 && tw->autoencrypt)
  595.             encrypt_start_output(tw, type);
  596.     }
  597. }
  598.  
  599. /*
  600.  * Called when a ENCRYPT START command is received.
  601.  */
  602. void encrypt_start (CDATA *tw, unsigned char *data, long cnt)
  603. {
  604.     #pragma unused (data, cnt)
  605.     Encryptions *ep;
  606.  
  607.     if (!tw->decrypt_mode) {
  608.         /*
  609.          * Something is wrong.    We should not get a START
  610.          * command without having already picked our
  611.          * decryption scheme.  Send a REQUEST-END to
  612.          * attempt to clear the channel...
  613.          */
  614.         xprintf(tw, "%s: Warning, Cannot decrypt input stream!!!\r\n", tw->Name);
  615.         encrypt_send_request_end(tw);
  616.         return;
  617.     }
  618.  
  619.     if (ep = finddecryption(tw, tw->decrypt_mode)) {
  620.         tw->decrypt_input = ep->input;
  621.         encryptStatechange(tw->wp);
  622. #ifdef notdef /* ddd */
  623.         (void) MyWDEFPatch(zoomDocProc , tw->wind, wDraw, kOurHit);
  624. #endif
  625.         if (tw->encrypt_verbose)
  626.             xprintf(tw, "[ Input is now decrypted with type %s ]\r\n",
  627.                    ENCTYPE_NAME(tw->decrypt_mode));
  628.         if (tw->encrypt_debug_mode)
  629.             xprintf(tw, ">>>%s: Start to decrypt input with type %s\r\n",
  630.                    tw->Name, ENCTYPE_NAME(tw->decrypt_mode));
  631.     } else {
  632.         xprintf(tw, "%s: Warning, Cannot decrypt type %s (%d)!!!\r\n",
  633.                tw->Name,
  634.                ENCTYPE_NAME_OK(tw->decrypt_mode)
  635.                ? ENCTYPE_NAME(tw->decrypt_mode)
  636.                : "(unknown)",
  637.                tw->decrypt_mode);
  638.         encrypt_send_request_end(tw);
  639.     }
  640. }
  641.  
  642. void encrypt_session_key (CDATA *tw, Session_Key *key, long server)
  643. {
  644.     Encryptions *ep = encryptions;
  645.  
  646.     tw->havesessionkey = 1;
  647.  
  648.     while (ep->type) {
  649.         if (ep->session)
  650.             (*ep->session)(tw, key, server);
  651. #ifdef notdef
  652.         if (!tw->encrypt_output && tw->autoencrypt && !server)
  653.             encrypt_start_output(tw, ep->type);
  654.         if (!tw->decrypt_input && tw->autodecrypt && !server)
  655.             encrypt_send_request_start(tw);
  656. #endif
  657.         ++ep;
  658.     }
  659. }
  660.  
  661. /*
  662.  * Called when ENCRYPT END is received.
  663.  */
  664. void encrypt_end (CDATA *tw)
  665. {
  666.     tw->decrypt_input = 0;
  667.     encryptStatechange(tw->wp);
  668. #ifdef notdef /* ddd */
  669.     (void) MyWDEFPatch(zoomDocProc , tw->wind, wDraw, kOurHit);
  670. #endif
  671.     if (tw->encrypt_debug_mode)
  672.         xprintf(tw, ">>>%s: Input is back to clear text\r\n", tw->Name);
  673.     if (tw->encrypt_verbose)
  674.         xprintf(tw, "[ Input is now clear text ]\r\n");
  675. }
  676.  
  677. /*
  678.  * Called when ENCRYPT REQUEST-END is received.
  679.  */
  680. void encrypt_request_end (CDATA *tw)
  681. {
  682.     encrypt_send_end(tw);
  683. }
  684.  
  685. /*
  686.  * Called when ENCRYPT REQUEST-START is received.  If we receive
  687.  * this before a type is picked, then that indicates that the
  688.  * other side wants us to start encrypting data as soon as we
  689.  * can. 
  690.  */
  691. void encrypt_request_start (CDATA *tw, unsigned char *data, long cnt)
  692. {
  693.     #pragma unused (data, cnt)
  694.     if (tw->encrypt_mode == 0)    {
  695.         if (tw->Server)
  696.             tw->autoencrypt = 1;
  697.         return;
  698.     }
  699.     encrypt_start_output(tw, tw->encrypt_mode);
  700. }
  701.  
  702. void encrypt_enc_keyid (CDATA *tw, unsigned char *keyid, long len)
  703. {
  704.     encrypt_keyid(tw, &tw->ki[1], keyid, len);
  705. }
  706.  
  707. void encrypt_dec_keyid (CDATA *tw, unsigned char *keyid, long len)
  708. {
  709.     encrypt_keyid(tw, &tw->ki[0], keyid, len);
  710. }
  711.  
  712. void encrypt_keyid (CDATA *tw, struct key_info *kp, unsigned char *keyid, long len)
  713. {
  714.     Encryptions *ep;
  715. #ifdef notdef
  716.     unsigned char *strp, *cp;
  717. #endif
  718.     long dir = kp->dir;
  719.     register long ret = 0;
  720.  
  721.     if (!(ep = (*kp->getcrypt)(tw, *kp->modep))) {
  722.         if (len == 0)
  723.             return;
  724.         kp->keylen = 0;
  725.     } else if (len == 0) {
  726.         /*
  727.          * Empty option, indicates a failure.
  728.          */
  729.         if (kp->keylen == 0)
  730.             return;
  731.         kp->keylen = 0;
  732.         if (ep->keyid)
  733.             (void)(*ep->keyid)(tw, dir, kp->keyid, &kp->keylen);
  734.  
  735.     } else if ((len != kp->keylen) || (xbcmp(keyid, kp->keyid, len) != 0)) {
  736.         /*
  737.          * Length or contents are different
  738.          */
  739.         kp->keylen = len;
  740.         xbcopy(keyid, kp->keyid, len);
  741.         if (ep->keyid)
  742.             (void)(*ep->keyid)(tw, dir, kp->keyid, &kp->keylen);
  743.  
  744.         if (tw->encrypt_debug_mode)
  745.             xprintf(tw, "encrypt_keyid: different dir=%d len=%d %d\n", dir, len, kp->keylen);
  746.     } else {
  747.         if (ep->keyid)
  748.             ret = (*ep->keyid)(tw, dir, kp->keyid, &kp->keylen);
  749.  
  750.         if (tw->encrypt_debug_mode)
  751.             xprintf(tw, "encrypt_keyid: ret=%d dir=%d autoe=%d\n",
  752.                     ret, dir, tw->autoencrypt);
  753.  
  754.         if ((ret == 0) && (dir == DIR_ENCRYPT) && tw->autoencrypt)
  755.             encrypt_start_output(tw, *kp->modep);
  756.         return;
  757.     }
  758.  
  759.     encrypt_send_keyid(tw, dir, kp->keyid, kp->keylen, 0);
  760. }
  761.  
  762.  
  763. void encrypt_send_keyid (CDATA *tw, long dir, unsigned char *keyid, long keylen, long saveit)
  764. {
  765.     unsigned char *strp;
  766.     
  767.     tw->str_keyid[0] = IAC;
  768.     tw->str_keyid[1] = SB;
  769.     tw->str_keyid[2] = OPT_ENCRYPT;
  770.     tw->str_keyid[3] = (dir == DIR_ENCRYPT)
  771.         ? ENCRYPT_ENC_KEYID : ENCRYPT_DEC_KEYID;
  772.  
  773.     if (saveit) {
  774.         struct key_info *kp = &tw->ki[(dir == DIR_ENCRYPT) ? 0 : 1];
  775.  
  776.         if (tw->encrypt_debug_mode)
  777.             xprintf(tw, "encrypt_send_keyid: saveit dir=%d keylen=%d id=%d\n", dir, keylen, *keyid);
  778.  
  779.         xbcopy(keyid, kp->keyid, keylen);
  780.         kp->keylen = keylen;
  781.     }
  782.  
  783.     for (strp = &tw->str_keyid[4]; keylen > 0; --keylen) {
  784.         if ((*strp++ = *keyid++) == IAC)
  785.             *strp++ = IAC;
  786.     }
  787.     *strp++ = IAC;
  788.     *strp++ = SE;
  789.     net_write(tw->wp, (char *)tw->str_keyid, strp - tw->str_keyid);
  790. /*    printsub(">", &tw->str_keyid[2], strp - tw->str_keyid - 2, tw); ddd */
  791. }
  792.  
  793. void encrypt_auto (CDATA *tw, long on)
  794. {
  795.     if (on < 0)
  796.         tw->autoencrypt ^= 1;
  797.     else
  798.         tw->autoencrypt = on ? 1 : 0;
  799. }
  800.  
  801. void decrypt_auto (CDATA *tw, long on)
  802. {
  803.     if (on < 0)
  804.         tw->autodecrypt ^= 1;
  805.     else
  806.         tw->autodecrypt = on ? 1 : 0;
  807. }
  808.  
  809. void encrypt_start_output (CDATA *tw, long type)
  810. {
  811.     Encryptions *ep;
  812.     register unsigned char *p;
  813.     register long i;
  814.  
  815.     if (!(ep = findencryption(tw, type))) {
  816.         if (tw->encrypt_debug_mode) {
  817.             xprintf(tw, ">>>%s: Can't encrypt with type %s (%d)\r\n",
  818.                    tw->Name,
  819.                    ENCTYPE_NAME_OK(type)
  820.                    ? ENCTYPE_NAME(type) : "(unknown)",
  821.                    type);
  822.         }
  823.         return;
  824.     }
  825.     if (ep->start) {
  826.         i = (*ep->start)(tw, DIR_ENCRYPT, tw->Server);
  827.         if (tw->encrypt_debug_mode) {
  828.             xprintf(tw, ">>>%s: Encrypt start: %s (%d) %s\r\n",
  829.                    tw->Name, 
  830.                    (i < 0) ? "failed" :
  831.                    "initial negotiation in progress",
  832.                    i, ENCTYPE_NAME(type));
  833.         }
  834.         if (i)
  835.             return;
  836.     }
  837.     p = tw->str_start + 3;
  838.     *p++ = ENCRYPT_START;
  839.     for (i = 0; i < tw->ki[0].keylen; ++i) {
  840.         if ((*p++ = tw->ki[0].keyid[i]) == IAC)
  841.             *p++ = IAC;
  842.     }
  843.     *p++ = IAC;
  844.     *p++ = SE;
  845.     
  846.     net_write(tw->wp, (char *)tw->str_start, p - tw->str_start);
  847.     net_encrypt();
  848. /*    printsub(">", &tw->str_start[2], p - &tw->str_start[2], tw); ddd */
  849.     /*
  850.      * If we are already encrypting in some mode, then
  851.      * encrypt the ring (which includes our request) in
  852.      * the old mode, mark it all as "clear text" and then
  853.      * switch to the new mode.
  854.      */
  855.     tw->encrypt_output = ep->output;
  856.     encryptStatechange(tw->wp);
  857. #ifdef notdef /* ddd */    
  858.     (void) MyWDEFPatch(zoomDocProc , tw->wind, wDraw, kOurHit);
  859. #endif
  860.     tw->encrypt_mode = type;
  861.     if (tw->encrypt_debug_mode)
  862.         xprintf(tw, ">>>%s: Started to encrypt output with type %s\r\n",
  863.                tw->Name, ENCTYPE_NAME(type));
  864.     if (tw->encrypt_verbose)
  865.         xprintf(tw, "[ Output is now encrypted with type %s ]\r\n",
  866.                ENCTYPE_NAME(type));
  867. }
  868.  
  869. void encrypt_send_end (CDATA *tw)
  870. {
  871.     if (!tw->encrypt_output)
  872.         return;
  873.  
  874.     tw->str_end[3] = ENCRYPT_END;
  875.     net_write(tw->wp, (char *)tw->str_end, sizeof(tw->str_end));
  876.     net_encrypt();
  877. /*    printsub(">", &tw->str_end[2], sizeof(tw->str_end) - 2, tw); ddd */
  878.     /*
  879.      * Encrypt the output buffer now because it will not be done by
  880.      * netflush...
  881.      */
  882.     tw->encrypt_output = 0;
  883.     encryptStatechange(tw->wp);
  884. #ifdef notdef /* ddd */
  885.     (void) MyWDEFPatch(zoomDocProc , tw->wind, wDraw, kOurHit);
  886. #endif
  887.     if (tw->encrypt_debug_mode)
  888.         xprintf(tw, ">>>%s: Output is back to clear text\r\n", tw->Name);
  889.     if (tw->encrypt_verbose)
  890.         xprintf(tw, "[ Output is now clear text ]\r\n");
  891. }
  892.  
  893. void encrypt_send_request_start (CDATA *tw)
  894. {
  895.     register unsigned char *p;
  896.     register long i;
  897.  
  898.     p = &tw->str_start[3];
  899.     *p++ = ENCRYPT_REQSTART;
  900.     for (i = 0; i < tw->ki[1].keylen; ++i) {
  901.         if ((*p++ = tw->ki[1].keyid[i]) == IAC)
  902.             *p++ = IAC;
  903.     }
  904.     *p++ = IAC;
  905.     *p++ = SE;
  906.     net_write(tw->wp, (char *)tw->str_start, p - tw->str_start);
  907. /*    printsub(">", &tw->str_start[2], p - &tw->str_start[2], tw); ddd */
  908.     if (tw->encrypt_debug_mode)
  909.         xprintf(tw, ">>>%s: Request input to be encrypted\r\n", tw->Name);
  910. }
  911.  
  912. void encrypt_send_request_end (CDATA *tw)
  913. {
  914.     tw->str_end[3] = ENCRYPT_REQEND;
  915.     net_write(tw->wp, (char *)tw->str_end, sizeof(tw->str_end));
  916. /*    printsub(">", &tw->str_end[2], sizeof(tw->str_end) - 2, tw); ddd */
  917.  
  918.     if (tw->encrypt_debug_mode)
  919.         xprintf(tw, ">>>%s: Request input to be clear text\r\n", tw->Name);
  920. }
  921.  
  922. #ifdef notdef
  923. void encrypt_wait (CDATA *tw)
  924. {
  925. #ifdef notdef
  926.     register long encrypt, decrypt;
  927. #endif
  928.  
  929.     if (tw->encrypt_debug_mode)
  930.         xprintf(tw, ">>>%s: in encrypt_wait\r\n", tw->Name);
  931.     if (!tw->havesessionkey || !(I_SUPPORT_ENCRYPT & tw->remote_supports_decrypt))
  932.         return;
  933.     while (tw->autoencrypt && !tw->encrypt_output)
  934.         if (telnet_spin())
  935.             return;
  936. }
  937. #endif
  938.  
  939. void encrypt_debug (CDATA *tw, long mode)
  940. {
  941.     tw->encrypt_debug_mode = mode;
  942. }
  943.  
  944. #ifdef notdef
  945. void encrypt_gen_printsub (unsigned char *data, long cnt, unsigned char *buf, long buflen)
  946. {
  947.     char tbuf[16], *cp;
  948.  
  949.     cnt -= 2;
  950.     data += 2;
  951.     buf[buflen-1] = '\0';
  952.     buf[buflen-2] = '*';
  953.     buflen -= 2;;
  954.     for (; cnt > 0; cnt--, data++) {
  955.         sprintf(tbuf, " %d", *data);
  956.         for (cp = tbuf; *cp && buflen > 0; --buflen)
  957.             *buf++ = *cp++;
  958.         if (buflen <= 0)
  959.             return;
  960.     }
  961.     *buf = '\0';
  962. }
  963.  
  964. void encrypt_printsub (unsigned char *data, long cnt, unsigned char *buf, long buflen)
  965. {
  966.     Encryptions *ep;
  967.     register long type = data[1];
  968.  
  969.     for (ep = encryptions; ep->type && ep->type != type; ep++)
  970.         ;
  971.  
  972.     if (ep->printsub)
  973.         (*ep->printsub)(data, cnt, buf, buflen);
  974.     else
  975.         encrypt_gen_printsub(data, cnt, buf, buflen);
  976. }
  977. #endif
  978.  
  979. #ifdef notdef
  980. void xxxprintsub (CDATA *tw, char direction, unsigned char *pointer, long length)
  981. {
  982.     char buf[256];
  983.  
  984.     if (tw->encrypt_debug_mode) {
  985.         sprintf(buf, "printsub: %c", direction);
  986.         hexout(pointer, length, buf);
  987.     }
  988. }
  989. #endif
  990.  
  991. void net_encrypt ()
  992. {
  993. }
  994.  
  995.  
  996. /*
  997.  * xprintf
  998.  */
  999. void xprintf (CDATA *cp, char *format, ...)
  1000. {
  1001. #pragma unused (cp, format)
  1002. #ifdef notdef
  1003.     char string[256];
  1004.     va_list args;
  1005.  
  1006.     va_start(args, format);
  1007.     vsprintf(string, format, args);
  1008.     sess_putln(dbgmsg, 0, cp);
  1009.     va_end(args);
  1010. #endif
  1011. }
  1012.  
  1013. /*
  1014.  * Junk so Emacs will set local variables to be compatible with Mac/MPW.
  1015.  * Should be at end of file.
  1016.  * 
  1017.  * Local Variables:
  1018.  * tab-width: 4
  1019.  * End:
  1020.  */
  1021.  
  1022.